package com.threepure.penpipe.floatbar;

import static android.os.Build.VERSION.SDK_INT;
import static android.view.animation.Animation.INFINITE;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import com.threepure.penpipe.R;

/**
 * @author ThreePure
 * @date 2021/11/15 8:50
 * @description: 悬浮条 【默认在屏幕上边缘】
 * @since 1.8
 */
public class FloatBar extends LinearLayout implements View.OnClickListener {

    private static final String TAG = "TP_FloatBar: ";

    /**展开的菜单（用于装多个菜单项） */
    private LinearLayout linearContent;
    /**linearContent的初始宽度*/
    private int mContentWidth;

    /**定义一个视图组 【视图组是可以包含其他视图（称为子视图）的特殊视图】*/
    private ViewGroup mViewGroup;
    /**mViewGroup的宽度*/
    private int mViewGroupWidth;

    /**悬浮窗是否展开*/
    private boolean isShow;

    /**是否吸附在左边缘*/
    private boolean isStickLift;
    /**是否吸附在右边缘*/
    private boolean isStickRight;


    /**隐藏在左侧位置【吸附边缘后显示logo显示的宽度】*/
    private float mStickLeftX;
    /**隐藏在右侧位置*/
    private float mStickRightX;

    /**当前悬浮窗的位置,true在左侧,否则在右侧*/
    private boolean currentPos = true;
    /**用于记录当前悬浮按钮的x，y坐标，用于判断画笔设置弹出框显示位置*/
    private float currentX;
    private float currentY;

    /**icon的宽度*/
    private int mLogoWidth;

    /**线程相关*/
    private Runnable autoStickRunnable;

    /**目的是避免悬浮窗展开或者收缩过程中，用户手抖多次点击。在执行此次任务后tempShow=false，在此次过程结束时设置为true  .只有在值为true时才能执行展开或收缩任务*/
    private boolean tempShow = true;

    /**悬浮球外侧的图片，当按住悬浮球拖动的时候，这个图片会旋转*/
    private View imgIconRotate;
    /**linearContent展开后与Logo之间的距离*/
    private int iconMargin;

    /**接口对象*/
    private FloatBarListener listener;

    public FloatBar(Activity context) {
        //调用这个类的第二个构造方法： public FloatBar(Context context, @Nullable AttributeSet attrs)
        this(context,null);
        if (context == null){
            throw new NullPointerException("Context 不能为空");
        }
    }

    public FloatBar(Context context, @Nullable AttributeSet attrs) {
        //调用这个类的第三个构造方法：  public FloatBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
        this(context, attrs,0);
    }

    public FloatBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        //描述如何定位子视图。源于 android.widget.LinearLayout  【将对象放置在其容器的垂直中心，不更改其大小】
        setGravity(Gravity.CENTER);
        //初始时悬浮按钮的Y轴坐标
        int defaultY = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
        iconMargin   = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
        int toppad   = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
        //设置linearContent的内边距
        linearContent.setPadding(iconMargin, 2, 0, 0);
        //悬浮球（悬浮菜单）的默认Y轴位置
        setY(defaultY);
    }


    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_undo:
                if (listener != null && tempShow){
                    listener.unDoClick();
                }
                break;
            case R.id.btn_redo:
                if (listener != null && tempShow){
                    listener.reDoClick();
                }
                break;
            case R.id.btn_pen:
                if (listener != null && tempShow){
                    listener.penClick();
                }
                break;
            case R.id.btn_eraser:
                if (listener != null && tempShow){
                    listener.eraserClick();
                }
                break;
            case R.id.btn_save:
                if (listener != null && tempShow){
                    listener.savaClick();
                }
                break;
            case R.id.btn_set:
                if (listener != null && tempShow){
                    listener.setClick();
                }
                break;
            default:
                break;
        }
        //shrinkWindow();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取默认宽度，并同设置宽度为零。将布局隐藏
        if (mContentWidth == 0){
            mLogoWidth = findViewById(R.id.float_icon).getMeasuredWidth();
            mContentWidth = linearContent.getMeasuredWidth();
            mStickLeftX   = -mLogoWidth * 1F / 3 * 2;
            ViewGroup.LayoutParams layoutParams = linearContent.getLayoutParams();
            layoutParams.width = 0;
        }
    }

    /**
     * @description:  FlowBar初始化
     * @Param: []
     * @Return: void
     */
    private void init() {
        //悬浮条的圆角半径【右上角、左下角】
        int radiusBottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 21, getResources().getDisplayMetrics());
        //悬浮条的圆角半径【左上角、右下角】
        int radius       = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5 , getResources().getDisplayMetrics());
        //内边距
        int padding      = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5 , getResources().getDisplayMetrics());
        //【整个悬浮菜单内边距】设置填充。根据滚动条的样式和可见性，视图可能会增加显示滚动条所需的空间。源于android.view.View
        setPadding(padding, padding, padding, padding);
        //绘制一个形状对象【菜单栏的整个背景（带圆角的矩形）】
        ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{radius, radius, radiusBottom, radiusBottom, radius, radius, radiusBottom, radiusBottom}, null, null));
        //0：为透明状态。这里是 初次进入到这个菜单的样式为透明。
        shapeDrawable.setAlpha(0);
        shapeDrawable.getPaint().setColor(Color.parseColor("#000000"));
        if (SDK_INT > 15){
            setBackground(shapeDrawable);
        }else {
            setBackgroundDrawable(shapeDrawable);
        }
        //将布局XML文件实例化为其相应的视图对象 android.View
        LayoutInflater.from(getContext()).inflate(R.layout.float_bar, this, true);

        /*以下获取布局文件上的控件等*/

        //展开的菜单
        linearContent = (LinearLayout) findViewById(R.id.linear_content);
        //悬浮球外侧的图片
        imgIconRotate = findViewById(R.id.img_icon_rotate);
        //为 “undo” 菜单项设置监听
        findViewById(R.id.btn_undo).setOnClickListener(this);
        //为 “redo” 菜单项设置监听
        findViewById(R.id.btn_redo).setOnClickListener(this);
        //为 “pen” 菜单项设置监听
        findViewById(R.id.btn_pen).setOnClickListener(this);
        //为 “eraser” 菜单项设置监听
        findViewById(R.id.btn_eraser).setOnClickListener(this);
        //为 “sava” 菜单项设置监听
        findViewById(R.id.btn_save).setOnClickListener(this);
        //为 “set” 菜单项设置监听
        findViewById(R.id.btn_set).setOnClickListener(this);
        //为悬浮按钮设置触摸监听【调用setIconTouchListener()方法】
        setIconTouchListener(findViewById(R.id.float_icon));
        //mViewGroup是 ViewGroup类变量
        mViewGroup =(ViewGroup) ((Activity) getContext()).getWindow().getDecorView().findViewById(android.R.id.content);
        if (mViewGroup != null){
            ViewParent parent = getParent();
            if(parent != null){
                ((ViewGroup) parent).removeView(this);
            }
            mViewGroup.addView(this, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        }
        //自动吸附左右边缘
        autoStickToEdge();
    }

    /**
     * @description:  悬浮按钮的触摸监听方法
     * @Param: [android.view.View] 悬浮按钮
     * @Return: void
     */
    private void setIconTouchListener(View flowIcon) {
        //setOnTouchListener:注册当触摸事件发送到此视图时要调用的回调。
        flowIcon.setOnTouchListener(new OnTouchListener() {
            //判定为移动操作的最小移动距离
            private int   touchSlop;
            //移动前的位置
            private float mTouchStarX;
            private float mTouchStarY;
            private float mOldX;
            private float mOldY;
            //此次滑动,悬浮窗将要吸在哪边  0--左边,1--右边,-1--都不是
            private int stickWhichPosition;
            //避免小距离的移动松手后被判断为点击
            private boolean moved;
            //避免点击时容易判断为移动
            private boolean canMove;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //实时位置
                float rawX = event.getRawX();
                float rawY = event.getRawY();
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        if (touchSlop == 0){
                            touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
                            mViewGroupWidth = mViewGroup.getWidth();
                            //吸附在右边界时logo的X坐标
                            mStickRightX = mViewGroupWidth - mLogoWidth * 3 / 4;
                        }
                        mOldX = mTouchStarX = rawX;
                        mOldY = mTouchStarY = rawY;
                        //现不确定悬浮条吸附在哪边
                        stickWhichPosition  = -1;
                        //如果getX() <0 即为true则吸附在左边
                        isStickLift  = getX() <0;
                        isStickRight = getX() + mLogoWidth > mViewGroupWidth;
                        moved = false;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        //float rawY = event.getRawY();
                        if (rawX < mOldX && getX() <= 0){
                            //左移超过
                            stickWhichPosition = 0;
                        } else if (rawX > mOldX && getX() >= mViewGroupWidth - getWidth()){
                            //右移超过
                            stickWhichPosition = 1;
                        } else if (rawY < mOldY && getY() <= 0){
                            //上移超过
                            setY(0);
                        } else if (rawY > mOldY && getY() >= mViewGroup.getHeight() - mLogoWidth) {
                            setY(mViewGroup.getHeight() - mLogoWidth);
                        } else {
                            stickWhichPosition = -1;
                            if (!canMove){
                                canMove = Math.abs(rawY - mOldY) > 5;
                            }
                            if (!isShow && canMove){
                                //悬浮窗展开时不能移动
                                setX(getX() + rawX - mOldX);
                                setY(getY() + rawY - mOldY);
                                currentX = getX() + rawX - mOldX;
                                currentY = getY() + rawY - mOldY;
                                Log.e(TAG, "onTouch: currentX:" + currentX );
                                Log.e(TAG, "onTouch: currentY:" + currentY );
                                //removeCallbacks:从消息队列中删除指定的Runnable。
                                removeCallbacks(autoStickRunnable);
                                //旋转悬浮图片周围的图片
                                rotateImage();
                                moved = true;
                            }
                        }
                        mOldX = rawX;
                        mOldY = rawY;
                        break;
                    case MotionEvent.ACTION_UP:
                        //停止旋转悬浮图片周围的图片
                        stopRotateImage();
                        canMove = false;
                        //位移
                        float moveX = Math.abs(mTouchStarX - rawX);
                        float moveY = Math.abs(mTouchStarY - rawY);

                        if (!(moveX >= touchSlop || moveY >= touchSlop) && !moved){
                            if (isStickLift){
                                // 如果此时状态为吸在两边中任意一边,则此时的点击响应为从边缘内拉出来,并且展开
                                ejectFromEdge(true);
                            }else if (isStickRight){
                                ejectFromEdge(false);
                            }else {
                                iconClick(v);
                            }
                            return true;
                        }
                        removeCallbacks(autoStickRunnable);
                        if (stickWhichPosition == 0){
                            //固定且半隐藏在左侧
                            stickToLeft();
                        } else if (stickWhichPosition == 1){
                            //固定且半隐藏在右侧
                            stickToRight();
                        } else {
                            if (isShow){
                                // 悬浮窗展开的时候不能移动
                                return true;
                            }
                            moveToEdge(rawX < mViewGroupWidth / 2);
                            autoStickToEdge();
                        }
                        break;
                    default:
                        break;
                }
                return true;
            }
        });
    }

    /**
     * @description:  自动吸附到边缘
     * @Param: []
     * @Return: void
     */
    private void autoStickToEdge() {
        //判断线程是否为空
        if (autoStickRunnable == null){
            autoStickRunnable = new Runnable() {
                @Override
                public void run() {
                    Log.e(TAG, "autoStickToEdge()--->run ");
                    //此处的10没有意义,只是判断是否在左边加的一个容错值
                    if (getX() < 10){
                        //固定且半隐藏在左侧
                        stickToLeft();
                    }else {
                        //固定且半隐藏在右侧
                        stickToRight();
                    }
                }
            };
        }
        //从消息队列中删除指定的Runnable（以被下一次用户拖动悬浮按钮）
        removeCallbacks(autoStickRunnable);
        //悬浮窗是否是展开状态（没有展开）
        if (!isShow){
            //使Runnable添加到消息队列中，并在指定的时间后运行。runnable将在用户界面线程上运行。
            postDelayed(autoStickRunnable, 2000);
        }
    }

    /**
     * @description:  悬浮按钮移动时 外围图标动画的方法
     * @Param: []
     * @Return: void
     */
    private void rotateImage() {
        if (imgIconRotate.getVisibility() == View.VISIBLE){
            return;
        }
        float y = getY() - mLogoWidth / 2;
        if (y > 0) {
            // 上移一点，避免被手指挡住
            setY(y);
        }
        //为外围图片设置旋转动画
        imgIconRotate.setVisibility(View.VISIBLE);
        ObjectAnimator animator = ObjectAnimator.ofFloat(imgIconRotate, ROTATION, 0, 360);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(INFINITE);
        animator.setDuration(1000);
        animator.start();
    }

    /**
     * @description:  悬浮按钮停止移动时，外围图标停止动画的方法
     * @Param: []
     * @Return: void
     */
    private void stopRotateImage() {
        imgIconRotate.clearAnimation();
        imgIconRotate.setVisibility(View.GONE);
    }

    /**
     * @description:  从边缘里面弹出来,并且展开悬浮窗
     * @Param: [boolean]
     * @Return: void
     */
    private void ejectFromEdge(boolean b) {
        int startDegree = 360;
        int endDegree   =   0;
        float startX = getX();
        float endX   = mViewGroupWidth - getWidth();

        if (b){
            //从左边弹出
            startDegree = endDegree;
            endDegree = 360;
            endX = 0;
        }

        ObjectAnimator animator = ObjectAnimator.ofFloat(this, ROTATION, startDegree, endDegree);
        ObjectAnimator ofFloat  = ObjectAnimator.ofFloat(this, TRANSLATION_X, startX, endX);

        AnimatorSet set = new AnimatorSet();
        set.setDuration(400).play(ofFloat).with(animator);
        set.start();
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                //展开悬浮窗
                openWindow();
            }
        });
    }

    /**
     * @description:  悬浮logo图标的点击事件,切换展开或收缩悬浮窗
     * @Param: [android.view.View]
     * @Return: void
     */
    private void iconClick(View v) {
        // tempShow目的是避免悬浮窗展开或者收缩过程中，用户手抖多次点击。在执行此次任务后tempShow=false，在此次过程结束时设置为true .只有在值为true时才能执行展开或收缩任务
        if (!tempShow){
            return;
        }
        if (isShow){
            //缩起悬浮窗
            shrinkWindow();
        }else {
            //展开悬浮窗
            openWindow();
        }
    }

    /**
     * @description:  固定且半隐藏在左侧
     * @Param: []
     * @Return: void
     */
    private void stickToLeft() {
        if (isShow){
            //缩起悬浮窗
            shrinkWindow();
            return;
        }
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(this, TRANSLATION_X, 0, -200);
        animator1.setDuration(500);

        ObjectAnimator animator2 = ObjectAnimator.ofFloat(this, TRANSLATION_X, -200, mStickLeftX / 1.2F);
        animator2.setDuration(200);

        ObjectAnimator animator3 = ObjectAnimator.ofFloat(this, TRANSLATION_X, mStickLeftX / 1.2F, mStickLeftX);
        animator3.setDuration(100);

        ObjectAnimator animator4 = ObjectAnimator.ofFloat(this, ROTATION, 360, 0);
        animator4.setDuration(400);

        AnimatorSet set = new AnimatorSet();
        set.play(animator4).with(animator1).before(animator2);
        set.setTarget(this);
        set.start();
    }

    /**
     * @description:  固定且半隐藏在右侧
     * @Param: []
     * @Return: void
     */
    private void stickToRight() {
        if (isShow){
            shrinkWindow();
            return;
        }
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(this, TRANSLATION_X, getX(), mViewGroupWidth + 200);
        animator1.setDuration(500);

        ObjectAnimator animator2 = ObjectAnimator.ofFloat(this, TRANSLATION_X, mViewGroupWidth + 200, mStickRightX);
        animator2.setDuration(200);

        ObjectAnimator animator3 = ObjectAnimator.ofFloat(this, ROTATION, 0, 360);
        animator3.setDuration(400);

        AnimatorSet set = new AnimatorSet();
        set.play(animator3).with(animator1).before(animator2);
        set.setTarget(this);
        set.start();
    }

    /**
     * @description:  从当前的位置移动到边缘
     * @Param: [boolean] true为移动到左边,false为移动到右边
     * @Return: void
     */
    private void moveToEdge(boolean b) {
        //前悬浮窗的位置,true在左侧,否则在右侧
        currentPos = b;
        float end = 0;
        if (!b){
            end = mViewGroupWidth - mLogoWidth - getPaddingRight() - getPaddingLeft();
        }
        //设置动画
        ObjectAnimator animator = ObjectAnimator.ofFloat(this, TRANSLATION_X, getX(), end);
        animator.setDuration(300);
        animator.start();
    }

    /**
     * @description:  展开悬浮窗
     * @Param: []
     * @Return: void
     */
    private void openWindow() {
        if (!isShow && !currentPos && tempShow){
            //如果此时在右边展开时要把悬浮窗往左边缘移动[将logo移动到右边缘]
            moveLogoToRight();
            //mContentWidth：linearContent的初始宽度
            ObjectAnimator animator = ObjectAnimator.ofFloat(this, TRANSLATION_X, getX(), getX() - mContentWidth);
            animator.setDuration(300);
            animator.start();
        }else {
            //将logo移动到左边缘
            moveLogoToLeft();
        }
        //切换悬浮窗的展开或收缩 【show 是否展开 true为展开】
        toggleWindowVisibility(true);
    }


    /**
     * @description:  缩起悬浮窗
     * @Param: []
     * @Return: void
     */
    private void shrinkWindow() {
        if (isShow && !currentPos && tempShow){
            //如果此时在右边,收起时要把悬浮窗移动到右边缘
            ObjectAnimator animator = ObjectAnimator.ofFloat(this, TRANSLATION_X, getX(), getX() + mContentWidth);
            animator.setDuration(300);
            animator.start();
        }
        //切换悬浮窗的展开或收缩
        toggleWindowVisibility(false);
    }

    /**
     * @description:  将logo移动到左边缘
     * @Param: []
     * @Return: void
     */
    private void moveLogoToLeft() {
        View childAt = getChildAt(getChildCount() - 1);
        if (childAt.getId() == R.id.layout_logo){
            //移除视图
            removeView(childAt);
            //添加子视图
            addView(childAt, 0);
            linearContent.setPadding(iconMargin, 0, 0, 0);
        }
    }

    /**
     * @description:  将logo移动到右边缘
     * @Param: []
     * @Return: void
     */
    private void moveLogoToRight() {
        View childAt = getChildAt(0);
        if (childAt.getId() == R.id.layout_logo){
            removeView(childAt);
            addView(childAt);
            linearContent.setPadding(0, 0, iconMargin, 0);
        }
    }

    /**
     * @description: 切换悬浮窗的展开或收缩 【show 是否展开 true为展开】
     * @Param: [boolean]
     * @Return: void
     */
    private void toggleWindowVisibility(boolean show) {
        if (!tempShow){
            return;
        }
        tempShow = false;

        removeCallbacks(autoStickRunnable);
        //配合悬浮窗显示或收起的动画  -->是否展开窗
        animateContent(show);

        int start =0;
        int end   =0;
        ValueAnimator valueAnimator = ValueAnimator.ofInt();
        if (show){
            //展开
            end = mContentWidth;
        } else {
            start = mContentWidth;
            valueAnimator.setInterpolator(new AnticipateInterpolator());
        }
        valueAnimator.setIntValues(start, end);
        valueAnimator.removeAllUpdateListeners();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value =  (int) animation.getAnimatedValue();
                Log.e("onAnimationUpdate", "mContentWidth = " + mContentWidth + ",value = " + value);
                ViewGroup.LayoutParams layoutParams = linearContent.getLayoutParams();
                layoutParams.width = value;
                linearContent.requestLayout();
            }
        });
        valueAnimator.setTarget(linearContent);
        valueAnimator.setDuration(300);
        valueAnimator.start();
    }

    /**
     * @description:  配合悬浮窗显示或收起的动画
     * @Param: [boolean]  是否展开窗
     * @Return: void
     */
    private void animateContent(boolean selected) {
        float start = 0F;
        float end   = 1F;
        float transStart = -400F;
        float transEnd   = 0F;
        int duration = 500;
        if (!selected){
            start = end;
            end   = 0F;
            transEnd   = transStart;
            transStart = 0F;
            duration   = 400;
        }

        ScaleAnimation scaleAnimation = new ScaleAnimation(start, end, 1, 1);
        scaleAnimation.setDuration(duration + 100);
        scaleAnimation.setRepeatCount(0);
        scaleAnimation.setFillAfter(true);
        scaleAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
        scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                isShow = getWidth() > mContentWidth;
                tempShow =true;
                if (!isShow){
                    autoStickToEdge();
                }else {
                    mContentWidth = refreshWidth();
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        ObjectAnimator animator = ObjectAnimator.ofFloat(linearContent, TRANSLATION_X, transStart, transEnd);
        animator.setDuration(duration);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                float alpha = Math.abs(value / 400) * 0.7F;
                getBackground().setAlpha((int) ((0.7 - alpha) * 255));
            }
        });
        animator.start();
        linearContent.startAnimation(scaleAnimation);
    }

    /**
     * @description:  更新内容的宽度，由于linerContent有一个预留隐藏的控件
     * @Param: []
     * @Return: int  内容布局宽度
     */
    private int refreshWidth() {
        int width = 0;
        int childCount = linearContent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childAt = linearContent.getChildAt(i);
            if (childAt.getVisibility() != View.GONE){
                MarginLayoutParams layoutParams = (MarginLayoutParams) childAt.getLayoutParams();
                width += layoutParams.leftMargin + layoutParams.rightMargin;
                width += childAt.getWidth();
            }
        }
        width += linearContent.getPaddingLeft() + linearContent.getPaddingRight();
        return width;
    }

    /**
     * @description:  悬浮按钮x的坐标
     * @Return: float  x坐标轴的值
     **/
    public float getCurrentX() {
        return currentX;
    }

    /**
     * @description:  悬浮按钮的y坐标
     * @Return: float  y坐标轴的值
     **/
    public float getCurrentY() {
        return currentY;
    }

    /**
     * @description: 获取图标宽度
     * @Return: int
     **/
    public int getmLogoWidth() {
        return mLogoWidth;
    }

    /**
     * @description:  点击事件的setter方法
     * @Param: [com.threepure.floatbar.FlowBar.FlowBarListener]
     * @Return: void
     */
    public void setFlowBarListener (FloatBarListener listener) {
        this.listener = listener;
    }

}
